package com.starling.extend.components
{
	import feathers.controls.Label;
	import feathers.controls.List;
	import feathers.controls.renderers.IListItemRenderer;
	import feathers.core.FeathersControl;
	import feathers.events.FeathersEventType;
	
	import flash.geom.Point;
	import flash.utils.Dictionary;
	
	import starling.events.Event;
	import starling.events.Touch;
	import starling.events.TouchEvent;
	import starling.events.TouchPhase;
	
	public class ListItemRender extends FeathersControl implements IListItemRenderer
	{
		public function ListItemRender()
		{
			super();
			this.isQuickHitAreaEnabled = true;
			this.addEventListener(TouchEvent.TOUCH, touchHandler);
			this.addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
		}
		
		
		
		
		
		/**********************************************************************************************
		 *  
		 * 								interface
		 * 
		 */		
		
		private var _data:Object;
		private var _index:int;
		private var _owner:List;
		private var _isSelected:Boolean;
		
		public function get data():Object {return _data;}
		public function get isSelected():Boolean {return _isSelected;}
		public function get index():int {return _index;}
		public function get owner():List {return List(_owner);}
		
		public function set data(value:Object):void 
		{
			if(this._data == value)return;
			this.touchPointID = -1;
			_data = value;
			this.invalidate(INVALIDATION_FLAG_DATA);
		}
		
		public function set isSelected(value:Boolean):void 
		{
			if(this._isSelected == value)return;
			_isSelected = value;
			this.invalidate(INVALIDATION_FLAG_DATA);
			this.dispatchEventWith(Event.CHANGE);
		}
		
		public function set index(value:int):void 
		{
			if(_index == value)return;
			_index = value;
			this.invalidate(INVALIDATION_FLAG_DATA);
		}
		
		public function set owner(value:List):void
		{
			if(this._owner == value)return;
			if(this._owner)
			{
				this._owner.removeEventListener(FeathersEventType.SCROLL_START, owner_scrollStartHandler);
				this._owner.removeEventListener(FeathersEventType.SCROLL_COMPLETE, owner_scrollCompleteHandler);
			}
			_owner = value;
			if(this._owner)
			{
				/*if(this.image)
				{
					this.image.delayTextureCreation = this._owner.isScrolling;
				}*/
				
				this._owner.addEventListener(FeathersEventType.SCROLL_START, owner_scrollStartHandler);
				this._owner.addEventListener(FeathersEventType.SCROLL_COMPLETE, owner_scrollCompleteHandler);
			}
			
			this.invalidate(INVALIDATION_FLAG_DATA);
		}
		
		
		
		
		
		
		
		
		
		/**********************************************************************************************
		 *  
		 * 										Event
		 * 
		 */
		
		protected function owner_scrollStartHandler(event:Event):void
		{
			this.touchPointID = -1;
			//this.image.delayTextureCreation = true;
		}
		
		protected function owner_scrollCompleteHandler(event:Event):void
		{
			//this.image.delayTextureCreation = false;
		}
		
		protected function removedFromStageHandler(event:Event):void
		{
			this.touchPointID = -1;
		}
		
		
		
		
		
		/**********************************************************************************************
		 *  
		 * 										override
		 * 
		 */
		
		private var _label:Label;
		
		override protected function initialize():void
		{
			if(!_label)
			{
				_label = new Label();
				_label.setSize(200 ,30);
				_label.textRendererProperties.color = 0x000000;
				addChild(_label);
			}
		}
		
		override protected function draw():void
		{
			const dataInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_DATA);
			const selectionInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_SELECTED);
			var sizeInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_SIZE);
			
			if(dataInvalid)
			{
				_label.text = _data?_data.toString():"";
			}
			
			sizeInvalid = autoSizeIfNeeded() || sizeInvalid;
			
			if(dataInvalid || sizeInvalid)
			{
				_label.width = this.actualWidth;
				_label.height = this.actualHeight;
			}
		}
		
		
		protected function autoSizeIfNeeded():Boolean
		{
			const needsWidth:Boolean = isNaN(this.explicitWidth);
			const needsHeight:Boolean = isNaN(this.explicitHeight);
			
			if(!needsWidth && !needsHeight)
			{
				return false;
			}
			
			this._label.width = NaN;
			this._label.height = NaN;
			this._label.validate();
			
			var newWidth:Number = this.explicitWidth;
			if(needsWidth)
			{
				//newWidth = this._label.width;
				
				if(!CACHED_BOUNDS.hasOwnProperty(this._index))
				{
					CACHED_BOUNDS[this._index] = new Point();
				}
				var boundsFromCache:Point = Point(CACHED_BOUNDS[this._index]);
				newWidth = boundsFromCache.x = this._label.width;
			}
			var newHeight:Number = this.explicitHeight;
			if(needsHeight)
			{
				//newHeight = this._label.height;
				
				if(!CACHED_BOUNDS.hasOwnProperty(this._index))
				{
					CACHED_BOUNDS[this._index] = new Point();
				}
				boundsFromCache = Point(CACHED_BOUNDS[this._index]);
				newHeight = boundsFromCache.y = this._label.height;
			}
			
			return this.setSizeInternal(newWidth, newHeight, false);
		}
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		/**********************************************************************************************
		 *  
		 * 										Touch
		 * 
		 */
		
		private var touchPointID:int;
		private static const HELPER_POINT:Point = new Point();
		private static const HELPER_TOUCHES_VECTOR:Vector.<Touch> = new <Touch>[];
		private static const CACHED_BOUNDS:Dictionary = new Dictionary(false);
		
		protected function touchHandler(event:TouchEvent):void
		{
			const touches:Vector.<Touch> = event.getTouches(this, null, HELPER_TOUCHES_VECTOR);
			if(touches.length == 0)
			{
				return;
			}
			if(this.touchPointID >= 0)
			{
				var touch:Touch;
				for each(var currentTouch:Touch in touches)
				{
					if(currentTouch.id == this.touchPointID)
					{
						touch = currentTouch;
						break;
					}
				}
				if(!touch)
				{
					HELPER_TOUCHES_VECTOR.length = 0;
					return;
				}
				if(touch.phase == TouchPhase.ENDED)
				{
					this.touchPointID = -1;
					
					touch.getLocation(this, HELPER_POINT);
					if(this.hitTest(HELPER_POINT, true) != null && !this._isSelected)
					{
						this.isSelected = true;
					}
				}
			}
			else
			{
				for each(touch in touches)
				{
					if(touch.phase == TouchPhase.BEGAN)
					{
						this.touchPointID = touch.id;
						break;
					}
				}
			}
			HELPER_TOUCHES_VECTOR.length = 0;
		}
	}
}